#!/usr/bin/env python3
"""
多因子评分系统 - Multi-Factor Scoring Model
专业级量化选股，集成技术面、基本面、动量、价值、质量等多个因子
"""

import numpy as np
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass
from enum import Enum
import logging
from datetime import datetime

# 导入技术指标模块
from .technical_indicators import TechnicalIndicatorCalculator, TechnicalIndicatorResult


class FactorType(Enum):
    """因子类型"""
    TECHNICAL = "技术面因子"
    FUNDAMENTAL = "基本面因子"
    MOMENTUM = "动量因子"
    VALUE = "价值因子"
    QUALITY = "质量因子"
    GROWTH = "成长因子"
    SENTIMENT = "情绪因子"


@dataclass
class FactorScore:
    """因子得分"""
    factor_type: FactorType
    score: float  # 0-100分
    weight: float  # 权重
    components: Dict[str, float]  # 子因子得分
    description: str


@dataclass
class StockFactorAnalysis:
    """股票因子分析结果"""
    stock_code: str
    stock_name: str
    factor_scores: Dict[FactorType, FactorScore]
    overall_score: float
    rank_percentile: float  # 排名百分位
    recommendation: str  # 强烈推荐/推荐/中性/不推荐
    confidence_level: float  # 置信度
    analysis_time: datetime


class MultiFactorModel:
    """多因子评分模型"""
    
    def __init__(self, factor_weights: Optional[Dict[FactorType, float]] = None):
        self.logger = logging.getLogger('MultiFactorModel')
        self.technical_calculator = TechnicalIndicatorCalculator()
        
        # 默认因子权重
        self.factor_weights = factor_weights or {
            FactorType.TECHNICAL: 0.25,
            FactorType.FUNDAMENTAL: 0.20,
            FactorType.MOMENTUM: 0.20,
            FactorType.VALUE: 0.15,
            FactorType.QUALITY: 0.10,
            FactorType.GROWTH: 0.10
        }
        
        # 确保权重总和为1
        total_weight = sum(self.factor_weights.values())
        if abs(total_weight - 1.0) > 0.01:  # 允许小的浮点误差
            for factor_type in self.factor_weights:
                self.factor_weights[factor_type] /= total_weight
    
    def analyze_stock(self, 
                     stock_code: str,
                     stock_name: str,
                     price_data: List[float],
                     volume_data: List[float],
                     fundamental_data: Optional[Dict] = None,
                     market_data: Optional[Dict] = None) -> StockFactorAnalysis:
        """分析单只股票的多因子得分"""
        
        try:
            factor_scores = {}
            
            # 1. 技术面因子分析
            factor_scores[FactorType.TECHNICAL] = self._calculate_technical_factor(
                price_data, volume_data
            )
            
            # 2. 基本面因子分析
            factor_scores[FactorType.FUNDAMENTAL] = self._calculate_fundamental_factor(
                fundamental_data, stock_code
            )
            
            # 3. 动量因子分析
            factor_scores[FactorType.MOMENTUM] = self._calculate_momentum_factor(
                price_data, volume_data
            )
            
            # 4. 价值因子分析
            factor_scores[FactorType.VALUE] = self._calculate_value_factor(
                fundamental_data, price_data
            )
            
            # 5. 质量因子分析
            factor_scores[FactorType.QUALITY] = self._calculate_quality_factor(
                fundamental_data
            )
            
            # 6. 成长因子分析
            factor_scores[FactorType.GROWTH] = self._calculate_growth_factor(
                fundamental_data
            )
            
            # 计算综合得分
            overall_score = self._calculate_overall_score(factor_scores)
            
            # 生成投资建议
            recommendation = self._generate_recommendation(overall_score, factor_scores)
            
            # 计算置信度
            confidence_level = self._calculate_confidence_level(price_data, factor_scores)
            
            return StockFactorAnalysis(
                stock_code=stock_code,
                stock_name=stock_name,
                factor_scores=factor_scores,
                overall_score=overall_score,
                rank_percentile=self._calculate_percentile(overall_score),
                recommendation=recommendation,
                confidence_level=confidence_level,
                analysis_time=datetime.now()
            )
            
        except Exception as e:
            self.logger.error(f"分析股票{stock_code}失败: {e}")
            return self._get_default_analysis(stock_code, stock_name)
    
    def _calculate_technical_factor(self, 
                                   price_data: List[float], 
                                   volume_data: List[float]) -> FactorScore:
        """计算技术面因子"""
        if len(price_data) < 10:
            return FactorScore(
                FactorType.TECHNICAL, 50.0, self.factor_weights[FactorType.TECHNICAL],
                {"data_insufficient": 50.0}, "数据不足"
            )
        
        # 计算技术指标
        indicators = self.technical_calculator.calculate_all_indicators(
            price_data, volume_data
        )
        
        # 技术面子因子得分
        components = {}
        
        # 趋势指标得分
        trend_score = 0
        trend_indicators = ['RSI', 'MACD', 'MA_SYSTEM']
        for indicator_name in trend_indicators:
            if indicator_name in indicators:
                indicator = indicators[indicator_name]
                if indicator.signal == "买入":
                    trend_score += indicator.strength
                elif indicator.signal == "卖出":
                    trend_score += (100 - indicator.strength)
                else:
                    trend_score += 50
        components['趋势强度'] = trend_score / len(trend_indicators) if trend_indicators else 50
        
        # 超买超卖指标得分
        overbought_score = 0
        overbought_indicators = ['RSI', 'KDJ', 'WILLIAMS_R']
        for indicator_name in overbought_indicators:
            if indicator_name in indicators:
                indicator = indicators[indicator_name]
                # RSI在30-70区间得分较高
                if indicator_name == 'RSI':
                    if 30 <= indicator.value <= 70:
                        overbought_score += 80
                    else:
                        overbought_score += max(20, 80 - abs(indicator.value - 50) * 1.5)
                else:
                    overbought_score += indicator.strength
        components['超买超卖'] = overbought_score / len(overbought_indicators) if overbought_indicators else 50
        
        # 价量配合得分
        volume_score = indicators.get('VOLUME', TechnicalIndicatorResult("VOLUME", 50, "持有", 50, "")).strength
        components['价量配合'] = volume_score
        
        # 波动性得分
        volatility_score = indicators.get('ATR', TechnicalIndicatorResult("ATR", 50, "持有", 50, "")).strength
        components['波动性'] = volatility_score
        
        # 支撑阻力得分
        bollinger = indicators.get('BOLLINGER', TechnicalIndicatorResult("BOLLINGER", 0.5, "持有", 50, ""))
        support_resistance_score = 100 - abs(bollinger.value - 0.5) * 200  # 价格在中轨附近得分高
        components['支撑阻力'] = max(0, support_resistance_score)
        
        # 计算技术面总分
        total_score = np.mean(list(components.values()))
        
        description = f"技术面综合评分，趋势强度{components['趋势强度']:.1f}，超买超卖{components['超买超卖']:.1f}"
        
        return FactorScore(
            FactorType.TECHNICAL, 
            total_score, 
            self.factor_weights[FactorType.TECHNICAL],
            components, 
            description
        )
    
    def _calculate_fundamental_factor(self, 
                                    fundamental_data: Optional[Dict], 
                                    stock_code: str) -> FactorScore:
        """计算基本面因子"""
        if not fundamental_data:
            # 生成模拟基本面数据
            fundamental_data = self._generate_mock_fundamental_data(stock_code)
        
        components = {}
        
        # 盈利能力得分
        roe = fundamental_data.get('roe', 0.15)  # ROE
        roa = fundamental_data.get('roa', 0.08)  # ROA
        net_margin = fundamental_data.get('net_margin', 0.10)  # 净利率
        
        profitability_score = (
            min(100, roe * 500) * 0.4 +  # ROE权重40%
            min(100, roa * 500) * 0.3 +  # ROA权重30%
            min(100, net_margin * 300) * 0.3  # 净利率权重30%
        )
        components['盈利能力'] = profitability_score
        
        # 财务健康度得分
        debt_ratio = fundamental_data.get('debt_ratio', 0.4)  # 资产负债率
        current_ratio = fundamental_data.get('current_ratio', 2.0)  # 流动比率
        quick_ratio = fundamental_data.get('quick_ratio', 1.5)  # 速动比率
        
        financial_health_score = (
            max(0, 100 - debt_ratio * 150) * 0.4 +  # 负债率越低越好
            min(100, (current_ratio - 1) * 40) * 0.3 +  # 流动比率适中最好
            min(100, (quick_ratio - 1) * 50) * 0.3  # 速动比率
        )
        components['财务健康'] = financial_health_score
        
        # 运营效率得分
        asset_turnover = fundamental_data.get('asset_turnover', 1.2)  # 资产周转率
        inventory_turnover = fundamental_data.get('inventory_turnover', 8.0)  # 存货周转率
        
        efficiency_score = (
            min(100, asset_turnover * 50) * 0.5 +
            min(100, inventory_turnover * 8) * 0.5
        )
        components['运营效率'] = efficiency_score
        
        # 现金流得分
        operating_cash_flow = fundamental_data.get('operating_cash_flow', 1.0)  # 经营现金流
        free_cash_flow = fundamental_data.get('free_cash_flow', 0.8)  # 自由现金流
        
        cash_flow_score = (
            min(100, max(0, operating_cash_flow * 80)) * 0.6 +
            min(100, max(0, free_cash_flow * 100)) * 0.4
        )
        components['现金流'] = cash_flow_score
        
        # 计算基本面总分
        total_score = np.mean(list(components.values()))
        
        description = f"基本面综合评分，盈利能力{components['盈利能力']:.1f}，财务健康{components['财务健康']:.1f}"
        
        return FactorScore(
            FactorType.FUNDAMENTAL, 
            total_score, 
            self.factor_weights[FactorType.FUNDAMENTAL],
            components, 
            description
        )
    
    def _calculate_momentum_factor(self, 
                                  price_data: List[float], 
                                  volume_data: List[float]) -> FactorScore:
        """计算动量因子"""
        if len(price_data) < 20:
            return FactorScore(
                FactorType.MOMENTUM, 50.0, self.factor_weights[FactorType.MOMENTUM],
                {"data_insufficient": 50.0}, "数据不足"
            )
        
        components = {}
        prices = np.array(price_data)
        volumes = np.array(volume_data)
        
        # 价格动量得分
        returns_1d = (prices[-1] - prices[-2]) / prices[-2] * 100 if len(prices) >= 2 else 0
        returns_5d = (prices[-1] - prices[-6]) / prices[-6] * 100 if len(prices) >= 6 else 0
        returns_20d = (prices[-1] - prices[-21]) / prices[-21] * 100 if len(prices) >= 21 else 0
        
        price_momentum_score = (
            self._normalize_return(returns_1d) * 0.2 +
            self._normalize_return(returns_5d) * 0.3 +
            self._normalize_return(returns_20d) * 0.5
        )
        components['价格动量'] = price_momentum_score
        
        # 成交量动量得分
        if len(volumes) >= 20:
            volume_ratio_5d = np.mean(volumes[-5:]) / np.mean(volumes[-20:-5])
            volume_momentum_score = min(100, (volume_ratio_5d - 0.5) * 100)
        else:
            volume_momentum_score = 50
        components['成交量动量'] = max(0, volume_momentum_score)
        
        # 相对强度得分
        if len(prices) >= 60:
            # 相对于60日均线的强度
            ma_60 = np.mean(prices[-60:])
            relative_strength = (prices[-1] - ma_60) / ma_60 * 100
            relative_strength_score = 50 + relative_strength * 2  # 转换为0-100分
        else:
            relative_strength_score = 50
        components['相对强度'] = max(0, min(100, relative_strength_score))
        
        # 趋势持续性得分
        if len(prices) >= 10:
            # 计算最近10日的趋势一致性
            daily_returns = np.diff(prices[-10:])
            positive_days = np.sum(daily_returns > 0)
            trend_consistency_score = (positive_days / len(daily_returns)) * 100
        else:
            trend_consistency_score = 50
        components['趋势持续性'] = trend_consistency_score
        
        # 计算动量总分
        total_score = np.mean(list(components.values()))
        
        description = f"动量因子评分，价格动量{components['价格动量']:.1f}，成交量动量{components['成交量动量']:.1f}"
        
        return FactorScore(
            FactorType.MOMENTUM, 
            total_score, 
            self.factor_weights[FactorType.MOMENTUM],
            components, 
            description
        )
    
    def _calculate_value_factor(self, 
                               fundamental_data: Optional[Dict], 
                               price_data: List[float]) -> FactorScore:
        """计算价值因子"""
        if not fundamental_data:
            fundamental_data = self._generate_mock_fundamental_data("default")
        
        components = {}
        
        # PE估值得分
        pe_ratio = fundamental_data.get('pe_ratio', 20.0)
        pe_score = max(0, 100 - max(0, pe_ratio - 15) * 3)  # PE越低得分越高
        components['PE估值'] = pe_score
        
        # PB估值得分
        pb_ratio = fundamental_data.get('pb_ratio', 2.0)
        pb_score = max(0, 100 - max(0, pb_ratio - 1.5) * 20)  # PB越低得分越高
        components['PB估值'] = pb_score
        
        # PS估值得分
        ps_ratio = fundamental_data.get('ps_ratio', 3.0)
        ps_score = max(0, 100 - max(0, ps_ratio - 2.0) * 15)  # PS越低得分越高
        components['PS估值'] = ps_score
        
        # 股息收益率得分
        dividend_yield = fundamental_data.get('dividend_yield', 0.02)
        dividend_score = min(100, dividend_yield * 2000)  # 股息率越高得分越高
        components['股息收益率'] = dividend_score
        
        # 账面价值得分
        book_value_per_share = fundamental_data.get('book_value_per_share', 10.0)
        current_price = price_data[-1] if price_data else 15.0
        pb_actual = current_price / book_value_per_share if book_value_per_share > 0 else 2.0
        book_value_score = max(0, 100 - max(0, pb_actual - 1.0) * 25)
        components['账面价值'] = book_value_score
        
        # 企业价值倍数得分
        ev_ebitda = fundamental_data.get('ev_ebitda', 12.0)
        ev_score = max(0, 100 - max(0, ev_ebitda - 10) * 5)
        components['企业价值倍数'] = ev_score
        
        # 计算价值总分
        total_score = np.mean(list(components.values()))
        
        description = f"价值因子评分，PE估值{components['PE估值']:.1f}，PB估值{components['PB估值']:.1f}"
        
        return FactorScore(
            FactorType.VALUE, 
            total_score, 
            self.factor_weights[FactorType.VALUE],
            components, 
            description
        )
    
    def _calculate_quality_factor(self, fundamental_data: Optional[Dict]) -> FactorScore:
        """计算质量因子"""
        if not fundamental_data:
            fundamental_data = self._generate_mock_fundamental_data("default")
        
        components = {}
        
        # ROE稳定性得分
        roe = fundamental_data.get('roe', 0.15)
        roe_stability = fundamental_data.get('roe_stability', 0.8)  # ROE稳定性系数
        roe_quality_score = min(100, roe * 400) * roe_stability
        components['ROE质量'] = roe_quality_score
        
        # 盈利质量得分
        net_income = fundamental_data.get('net_income', 1.0)
        operating_cash_flow = fundamental_data.get('operating_cash_flow', 1.0)
        earnings_quality = operating_cash_flow / net_income if net_income > 0 else 1.0
        earnings_quality_score = min(100, earnings_quality * 80)
        components['盈利质量'] = earnings_quality_score
        
        # 资产质量得分
        total_assets = fundamental_data.get('total_assets', 10.0)
        intangible_assets = fundamental_data.get('intangible_assets', 1.0)
        asset_quality = 1 - (intangible_assets / total_assets) if total_assets > 0 else 0.8
        asset_quality_score = asset_quality * 100
        components['资产质量'] = asset_quality_score
        
        # 财务杠杆得分
        debt_ratio = fundamental_data.get('debt_ratio', 0.4)
        leverage_score = max(0, 100 - debt_ratio * 150)  # 杠杆越低得分越高
        components['财务杠杆'] = leverage_score
        
        # 管理效率得分
        asset_turnover = fundamental_data.get('asset_turnover', 1.2)
        management_efficiency_score = min(100, asset_turnover * 60)
        components['管理效率'] = management_efficiency_score
        
        # 计算质量总分
        total_score = np.mean(list(components.values()))
        
        description = f"质量因子评分，ROE质量{components['ROE质量']:.1f}，盈利质量{components['盈利质量']:.1f}"
        
        return FactorScore(
            FactorType.QUALITY, 
            total_score, 
            self.factor_weights[FactorType.QUALITY],
            components, 
            description
        )
    
    def _calculate_growth_factor(self, fundamental_data: Optional[Dict]) -> FactorScore:
        """计算成长因子"""
        if not fundamental_data:
            fundamental_data = self._generate_mock_fundamental_data("default")
        
        components = {}
        
        # 营收增长得分
        revenue_growth = fundamental_data.get('revenue_growth', 0.10)
        revenue_growth_score = min(100, max(0, revenue_growth * 300))
        components['营收增长'] = revenue_growth_score
        
        # 净利润增长得分
        profit_growth = fundamental_data.get('profit_growth', 0.12)
        profit_growth_score = min(100, max(0, profit_growth * 250))
        components['净利润增长'] = profit_growth_score
        
        # ROE增长得分
        roe_growth = fundamental_data.get('roe_growth', 0.05)
        roe_growth_score = min(100, max(0, roe_growth * 400))
        components['ROE增长'] = roe_growth_score
        
        # 营业现金流增长得分
        cash_flow_growth = fundamental_data.get('cash_flow_growth', 0.08)
        cash_flow_growth_score = min(100, max(0, cash_flow_growth * 300))
        components['现金流增长'] = cash_flow_growth_score
        
        # 市场份额增长得分（模拟）
        market_share_growth = fundamental_data.get('market_share_growth', 0.03)
        market_share_score = min(100, max(0, market_share_growth * 500))
        components['市场份额增长'] = market_share_score
        
        # 计算成长总分
        total_score = np.mean(list(components.values()))
        
        description = f"成长因子评分，营收增长{components['营收增长']:.1f}，净利润增长{components['净利润增长']:.1f}"
        
        return FactorScore(
            FactorType.GROWTH, 
            total_score, 
            self.factor_weights[FactorType.GROWTH],
            components, 
            description
        )
    
    def _calculate_overall_score(self, factor_scores: Dict[FactorType, FactorScore]) -> float:
        """计算综合得分"""
        weighted_score = 0
        total_weight = 0
        
        for factor_type, factor_score in factor_scores.items():
            weighted_score += factor_score.score * factor_score.weight
            total_weight += factor_score.weight
        
        return weighted_score / total_weight if total_weight > 0 else 50.0
    
    def _generate_recommendation(self, 
                               overall_score: float, 
                               factor_scores: Dict[FactorType, FactorScore]) -> str:
        """生成投资建议"""
        if overall_score >= 80:
            return "强烈推荐"
        elif overall_score >= 65:
            return "推荐"
        elif overall_score >= 45:
            return "中性"
        else:
            return "不推荐"
    
    def _calculate_confidence_level(self, 
                                   price_data: List[float], 
                                   factor_scores: Dict[FactorType, FactorScore]) -> float:
        """计算置信度"""
        base_confidence = 60.0
        
        # 数据充分性加分
        if len(price_data) >= 60:
            base_confidence += 20
        elif len(price_data) >= 20:
            base_confidence += 10
        
        # 因子一致性加分
        high_score_factors = sum(1 for fs in factor_scores.values() if fs.score >= 70)
        if high_score_factors >= 4:
            base_confidence += 15
        elif high_score_factors >= 2:
            base_confidence += 10
        
        return min(95.0, base_confidence)
    
    def _calculate_percentile(self, score: float) -> float:
        """计算排名百分位（简化版）"""
        # 简化的百分位计算，实际应基于历史数据分布
        if score >= 80:
            return 95.0
        elif score >= 70:
            return 80.0
        elif score >= 60:
            return 65.0
        elif score >= 50:
            return 50.0
        elif score >= 40:
            return 35.0
        else:
            return 20.0
    
    def _normalize_return(self, return_pct: float) -> float:
        """标准化收益率为0-100分"""
        # 将收益率转换为0-100分，0%收益率对应50分
        if return_pct > 0:
            return min(100, 50 + return_pct * 5)
        else:
            return max(0, 50 + return_pct * 5)
    
    def _generate_mock_fundamental_data(self, stock_code: str) -> Dict:
        """生成模拟基本面数据"""
        # 根据股票代码生成相对合理的模拟数据
        hash_code = hash(stock_code) % 1000
        
        return {
            'pe_ratio': 15 + (hash_code % 30),
            'pb_ratio': 1.5 + (hash_code % 50) / 10,
            'ps_ratio': 2.0 + (hash_code % 40) / 10,
            'roe': 0.08 + (hash_code % 20) / 100,
            'roa': 0.05 + (hash_code % 15) / 100,
            'net_margin': 0.08 + (hash_code % 25) / 100,
            'debt_ratio': 0.3 + (hash_code % 40) / 100,
            'current_ratio': 1.2 + (hash_code % 30) / 10,
            'quick_ratio': 1.0 + (hash_code % 25) / 10,
            'asset_turnover': 0.8 + (hash_code % 20) / 10,
            'inventory_turnover': 6 + (hash_code % 10),
            'operating_cash_flow': 0.8 + (hash_code % 40) / 100,
            'free_cash_flow': 0.6 + (hash_code % 30) / 100,
            'dividend_yield': 0.01 + (hash_code % 40) / 1000,
            'book_value_per_share': 8 + (hash_code % 20),
            'ev_ebitda': 10 + (hash_code % 15),
            'roe_stability': 0.7 + (hash_code % 25) / 100,
            'net_income': 1.0 + (hash_code % 50) / 100,
            'total_assets': 10 + (hash_code % 100),
            'intangible_assets': 1 + (hash_code % 20) / 10,
            'revenue_growth': 0.05 + (hash_code % 25) / 100,
            'profit_growth': 0.03 + (hash_code % 35) / 100,
            'roe_growth': 0.02 + (hash_code % 20) / 100,
            'cash_flow_growth': 0.04 + (hash_code % 30) / 100,
            'market_share_growth': 0.01 + (hash_code % 15) / 100
        }
    
    def _get_default_analysis(self, stock_code: str, stock_name: str) -> StockFactorAnalysis:
        """获取默认分析结果"""
        default_factor_score = FactorScore(
            FactorType.TECHNICAL, 50.0, 0.2, {"default": 50.0}, "数据不足"
        )
        
        factor_scores = {
            factor_type: FactorScore(factor_type, 50.0, weight, {"default": 50.0}, "数据不足")
            for factor_type, weight in self.factor_weights.items()
        }
        
        return StockFactorAnalysis(
            stock_code=stock_code,
            stock_name=stock_name,
            factor_scores=factor_scores,
            overall_score=50.0,
            rank_percentile=50.0,
            recommendation="中性",
            confidence_level=40.0,
            analysis_time=datetime.now()
        )
    
    def display_analysis_result(self, analysis: StockFactorAnalysis):
        """显示分析结果"""
        print(f"\n{'='*80}")
        print(f"📊 多因子分析报告 - {analysis.stock_name}({analysis.stock_code})")
        print(f"{'='*80}")
        
        print(f"\n🎯 综合评分: {analysis.overall_score:.1f}/100")
        print(f"📈 排名百分位: {analysis.rank_percentile:.1f}%")
        print(f"💡 投资建议: {analysis.recommendation}")
        print(f"🎲 置信度: {analysis.confidence_level:.1f}%")
        print(f"⏰ 分析时间: {analysis.analysis_time.strftime('%Y-%m-%d %H:%M:%S')}")
        
        print(f"\n📋 因子得分详情:")
        for factor_type, factor_score in analysis.factor_scores.items():
            print(f"   {factor_type.value}: {factor_score.score:.1f}/100 (权重:{factor_score.weight:.1%})")
            print(f"      {factor_score.description}")
            
            # 显示子因子得分
            if len(factor_score.components) > 1:
                for component_name, component_score in factor_score.components.items():
                    if component_name != "default" and component_name != "data_insufficient":
                        print(f"        • {component_name}: {component_score:.1f}")
        
        print(f"\n{'='*80}")


def create_multi_factor_model(factor_weights: Optional[Dict[FactorType, float]] = None) -> MultiFactorModel:
    """创建多因子模型实例"""
    return MultiFactorModel(factor_weights)


if __name__ == "__main__":
    # 测试多因子模型
    model = create_multi_factor_model()
    
    # 模拟数据测试
    test_prices = [10.0, 10.2, 10.1, 10.3, 10.5, 10.4, 10.6, 10.8, 10.7, 10.9,
                   11.0, 10.9, 11.1, 11.3, 11.2, 11.4, 11.6, 11.5, 11.7, 11.9]
    test_volumes = [1000000] * len(test_prices)
    
    analysis = model.analyze_stock("601611", "中国核建", test_prices, test_volumes)
    model.display_analysis_result(analysis) 